/*
Pyxis 2.0
Copyright 2010-2011 Thomas W. Holtquist

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Threading;

using Microsoft.SPOT;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Time;

using GHIElectronics.NETMF.Hardware;

using Skewworks.Pyxis.Drivers;
using Skewworks.Pyxis.EXT;
using Skewworks.Pyxis.GUI.Controls;

namespace Skewworks.Pyxis.Kernel
{
    internal static class SettingsWin
    {

        #region Variables

        private static PyxisAPI API;
        private static bool bLoaded = false;
        private static MenuItem AppMenu = null;
        private static Form frmMain = null;
        private static Form frmSub = null;
        private static MenuItem mnuQuitApp;
        private static MenuItem mnuSwitchToApp;
        private static Bitmap buffer2 = null;                   // Buffer for Modal
        private static ArrayList _services = new ArrayList();   // List of Services
        private static ModalMessage MM;
        #endregion

        #region Public Methods

        public static void Show(PyxisAPI api)
        {

            API = api;
            if (API.desktop._mnu.count > 1) API.desktop._mnu.remove(1);

            if (!bLoaded)
            {
                MM = new ModalMessage("Loading Settings; Please Wait", api);
                new Thread(CreateApp).Start();
                MM.Start();
                bLoaded = true;
            }

            // Display App
            API.desktop._mnu.add(AppMenu);
            API.ActiveForm = frmMain;

        }

        public static void Quit()
        {
            if (!bLoaded)
                return;

            API.desktop.mnuRun.RemoveItem(mnuSwitchToApp);
            API.desktop.mnuForce.RemoveItem(mnuQuitApp);
            if (API.desktop.mnuForce.ItemCount == 0) API.desktop.mnuForce.Enabled = false;
            if (API.desktop.mnuRun.ItemCount == 0) API.desktop.mnuRun.Enabled = false;

            API.DisplayDesktop();

            frmMain.ClearChildren();
            frmMain = null;
            frmSub.ClearChildren();
            frmSub = null;
            mnuQuitApp = null;
            mnuSwitchToApp = null;
            AppMenu = null;

            bLoaded = false;
        }

        #endregion

        #region Private Methods

        private static void BrowseWallpaper(Textbox txtWall)
        {
            string sVal = API.OpenFile("Select Wallpaper", API.MyDrives.RootDirectory + "\\pyxis\\wallpapers\\", new string[] { ".jpg", ".jpe", ".jpeg", ".bmp", ".gif" });
            if (sVal != string.Empty) txtWall.Text = sVal;
        }

        private static void CreateApp()
        {
            IconShortcut ico;
            int x = 0;
            int y = 4;

            Thread.Sleep(100);

            CreateMenus();

            // Create Form
            frmMain = new Form(API, Colors.White, true, true);
            frmSub = new Form(API, Colors.LightGray, true, true);

            ico = new IconShortcut(new Image32(Resources.GetBytes(Resources.BinaryResources.appearance)), "Appearance", x, y, 76, 69);
            ico.tapEvent += new OnTap((object sender, point e) => ShowAppearance());
            frmMain.AddChild(ico);
            AdjustXY(ref x, ref y);

            ico = new IconShortcut(new Image32(Resources.GetBytes(Resources.BinaryResources.network)), "Network", x, y, 76, 69);
            ico.tapEvent += new OnTap((object sender, point e) => ShowNetwork());
            frmMain.AddChild(ico);
            AdjustXY(ref x, ref y);

            ico = new IconShortcut(new Image32(Resources.GetBytes(Resources.BinaryResources.time)), "Date / Time", x, y, 76, 69);
            ico.tapEvent += new OnTap((object sender, point e) => ShowDateTime());
            frmMain.AddChild(ico);
            AdjustXY(ref x, ref y);

            ico = new IconShortcut(new Image32(Resources.GetBytes(Resources.BinaryResources.services)), "Services", x, y, 76, 69);
            ico.tapEvent += new OnTap((object sender, point e) => ShowServices());
            frmMain.AddChild(ico);
            AdjustXY(ref x, ref y);

            if (DeviceManager.ActiveDevice == DeviceType.ChipworkX || DeviceManager.ActiveDevice == DeviceType.Emulator)
            {
                ico = new IconShortcut(new Image32(Resources.GetBytes(Resources.BinaryResources.sound)), "Sounds", x, y, 76, 69);
                ico.tapEvent += new OnTap((object sender, point e) => ShowSounds());
                frmMain.AddChild(ico);
                AdjustXY(ref x, ref y);
            }

            MM.Stop();
        }

        private static void AdjustXY(ref int X, ref int Y)
        {
            X += 80;
            if (X > AppearanceManager.ScreenWidth - 80)
            {
                X = 0;
                Y += 74;
            }
        }

        private static void CreateMenus()
        {

            // Create Menus
            AppMenu = new MenuItem("Settings");
            MenuItem mnuExit = new MenuItem("Quit");
            mnuExit.tapEvent += new MenuItemTap((object sender) => Quit());
            AppMenu.AddItem(mnuExit);
            
            // Create Switch/Quit Menus
            mnuSwitchToApp = new MenuItem("Settings");
            mnuSwitchToApp.tapEvent += new MenuItemTap((object sender) => Show(API));
            mnuSwitchToApp.Tag = "Settings";
            API.desktop.mnuRun.AddItem(mnuSwitchToApp);
            API.desktop.mnuRun.Enabled = true;

            mnuQuitApp = new MenuItem("Settings");
            mnuQuitApp.tapEvent += new MenuItemTap((object sender) => Quit());
            mnuQuitApp.Tag = "Settings";
            API.desktop.mnuForce.AddItem(mnuQuitApp);
            API.desktop.mnuForce.Enabled = true;
        }

        private static void ShowAppearance()
        {
            frmSub.ClearChildren();

            frmSub.AddChild(new Label("Wallpaper:", 4, 8));

            Textbox txtWall = new Textbox("", 64, 6, frmSub.Width - 154, 20);
            frmSub.AddChild(txtWall);

            Combobox cboDisplay = new Combobox(64, 30, 80, 20, new string[] { "{None}", "Normal", "Stretch", "Scale", "Center", "Tile" });
            frmSub.AddChild(cboDisplay);

            CommandButton btnBrowse = new CommandButton("Browse", frmSub.Width - 87, 4);
            btnBrowse.tapEvent += new OnTap((object sender, point e) => BrowseWallpaper(txtWall));
            frmSub.AddChild(btnBrowse);

            frmSub.AddChild(new Label("Backcolor: ", 4, 62));
            Picturebox pbColor = new Picturebox(null, 64, 60, 40, 20);
            pbColor.BorderStyle = BorderStyle.BorderFlat;
            frmSub.AddChild(pbColor);
            CommandButton cmdChange = new CommandButton("Change", 108, 58);
            cmdChange.tapEvent += new OnTap((object sender, point e) => pbColor.Background = API.SelectColor(pbColor.Background));
            frmSub.AddChild(cmdChange);

            frmSub.AddChild(new Label("Display on Desktop:", 4, 85));

            Checkbox chkAppStore = new Checkbox(4, 105);
            frmSub.AddChild(chkAppStore);
            frmSub.AddChild(new Label("App Market", 24, 105));

            Checkbox chkFinder = new Checkbox(124, 105);
            frmSub.AddChild(chkFinder);
            frmSub.AddChild(new Label("File Finder", 144, 105));

            Checkbox chkViewer = new Checkbox(4, 130);
            frmSub.AddChild(chkViewer);
            frmSub.AddChild(new Label("Picture Viewer", 24, 130));

            Checkbox chkSettings = new Checkbox(124, 130);
            frmSub.AddChild(chkSettings);
            frmSub.AddChild(new Label("Settings", 144, 130));

            if (API.MyDrives.RootDirectory == "\\")
            {
                btnBrowse.Enabled = false;
                txtWall.Text = "[System Default]";
                txtWall.Enabled = false;
                cboDisplay.Enabled = false;
                chkAppStore.Enabled = false;
                chkFinder.Enabled = false;
                chkSettings.Enabled = false;
                chkViewer.Enabled = false;
                pbColor.Background = ColorUtility.ColorFromRGB(15, 163, 224);
                cmdChange.Enabled = false;
            }
            else
            {
                // Read system settings
                XMLReaderEX xr = new XMLReaderEX(API.MyDrives.RootDirectory + "\\pyxis\\system\\desktop.Xml");
                XMLNodeEX node = (XMLNodeEX)xr.Nodes[0];
                node = node.NodeByName("Appearance");
                string sPaper = node.NodeByName("Wallpaper").value;
                if (sPaper.IndexOf("\\") < 0) sPaper = API.MyDrives.RootDirectory + "pyxis\\wallpapers\\" + sPaper;
                txtWall.Text = sPaper;
                chkAppStore.Value = (node.NodeByName("ShowAppStore").value == "1") ? true : false;
                chkFinder.Value = (node.NodeByName("ShowFileFinder").value == "1") ? true : false;
                chkSettings.Value = (node.NodeByName("ShowSettings").value == "1") ? true : false;
                chkViewer.Value = (node.NodeByName("ShowPictureViewer").value == "1") ? true : false;
                string[] vals = node.NodeByName("Backcolor").value.Split(',');
                pbColor.Background = ColorUtility.ColorFromRGB(byte.Parse(vals[0]), byte.Parse(vals[1]), byte.Parse(vals[2]));
                cboDisplay.SelectedIndex = int.Parse(node.NodeByName("WallpaperMode").value) + 1;
            }

            CommandButton btnCancel = new CommandButton("Cancel", frmSub.Width - 79, frmSub.Height - 29);
            btnCancel.tapEvent += new OnTap((object sender, point e) => API.ActiveForm = frmMain);
            frmSub.AddChild(btnCancel);

            CommandButton btnOK = new CommandButton("Save", frmSub.Width - 158, frmSub.Height - 29);
            btnOK.tapEvent += new OnTap((object sender, point e) => SaveAppearance(txtWall, pbColor.Background, cboDisplay, chkAppStore, chkFinder, chkViewer, chkSettings));
            frmSub.AddChild(btnOK);

            API.ActiveForm = frmSub;
        }

        private static void ShowDateTime()
        {
            frmSub.ClearChildren();

            Checkbox chkRTC = new Checkbox(4, 4);
            if (DeviceManager.ActiveDevice == DeviceType.ChipworkX)
            {
                chkRTC.Value = true;
                chkRTC.Enabled = false;
            }
            else
            {
                chkRTC.Value = SettingsManager.BootSettings.EnableRTC;
            }
            frmSub.AddChild(chkRTC);
            frmSub.AddChild(new Label("Enable Real-Time Clock", 24, 5));

            Combobox cboMonth = new Combobox(24, 28, 90, 20, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "Septemper", "October", "November", "December" });
            cboMonth.SelectedIndex = DateTime.Now.Month - 1;
            cboMonth.Enabled = chkRTC.Value;
            frmSub.AddChild(cboMonth);

            NumericUpDown numDay = new NumericUpDown(116, 28, 35, 1, 31, DateTime.Now.Day);
            numDay.Enabled = chkRTC.Value;
            frmSub.AddChild(numDay);

            NumericUpDown numYear = new NumericUpDown(154, 28, 54, 2010, 2210, DateTime.Now.Year);
            numYear.Enabled = chkRTC.Value;
            frmSub.AddChild(numYear);

            NumericUpDown numHour = new NumericUpDown(24, 52, 35, 1, 12, (DateTime.Now.Hour > 12) ? DateTime.Now.Hour - 12 : DateTime.Now.Hour);
            numHour.Enabled = chkRTC.Value;
            frmSub.AddChild(numHour);
            frmSub.AddChild(new Label(":", 62, 53));
            NumericUpDown numMin = new NumericUpDown(67, 52, 35, 0, 59, DateTime.Now.Minute);
            numMin.Enabled = chkRTC.Value;
            numMin.ForceZeros = true;
            frmSub.AddChild(numMin);
            frmSub.AddChild(new Label(":", 105, 53));
            NumericUpDown numSec = new NumericUpDown(110, 52, 35, 0, 59, DateTime.Now.Second);
            numSec.Enabled = chkRTC.Value;
            numSec.ForceZeros = true;
            frmSub.AddChild(numSec);
            Combobox cboAP = new Combobox(148, 52, 45, 20, new string[] { "AM", "PM" });
            cboAP.Enabled = chkRTC.Value;
            cboAP.SelectedIndex = (DateTime.Now.Hour > 12) ? 1 : 0;
            frmSub.AddChild(cboAP);

            string[] timeZones = new string[] { 
                "(-12:00) International Dateline West",             // 0
                "(-11:00) Coordinated Universal Time -11",          // 1
                "(-11:00) Samoa",
                "(-10:00) Hawaii",           // 3
                "(-09:00) Alaska",          // 4
                "(-08:00) Baja California",          // 5
                "(-08:00) Pacific Time (US & Canada)",
                "(-07:00) Arizona",                 // 7
                "(-07:00) Chihuahua, La Paz, Mazatlan",
                "(-07:00) Mountain Time (US & Canada)",  
                "(-06:00) Central America",          // 10
                "(-06:00) Central Time (US & Canada)", 
                "(-06:00) Guadalajara, Mexico City, Monterrey",
                "(-06:00) Saskatchewan", 
                "(-05:00) Bogota, Lima, Quito",          // 14
                "(-05:00) Eastern Time (US & Canada)", 
                "(-05:00) India (East)",
                "(-04:30) Caracas",          // 17
                "(-04:00) Asuncion",          // 18
                "(-04:00) Atlantic Time (Canada)",
                "(-04:00) Cuiaba",
                "(-04:00) Georgetown, La Paz, Manaus, San Juan",       
                "(-04:00) Santiago",
                "(-03:30) Newfoundland",            // 23
                "(-03:00) Brasilia",          // 24
                "(-03:00) Buenos Aires", 
                "(-03:00) Cayenne, Fortaleza",
                "(-03:00) Greenland", 
                "(-03:00) Montevideo",
                "(-02:00) Coordianted Universal Time -02",           // 29
                "(-02:00) Mid-Atlantic",
                "(-01:00) Azores",          // 31
                "(-01:00) Cape Verde Is.",
                "( 00:00) Casablanca",            // 33
                "( 00:00) Coordinated Universal Time",
                "( 00:00) Dublin, Edinburgh, Lisbon, London", 
                "( 00:00) Monrovia, Reykjavik",
                "(+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna",           // 37
                "(+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague",
                "(+01:00) Brussels, Copenhagen, Madrid, Paris", 
                "(+01:00) Sarajevo, Skopje, Warsaw, Zagreb",
                "(+01:00) West Central Africa",
                "(+01:00) Windhoek",
                "(+02:00) Amman",            // 43
                "(+02:00) Athens, Bucharest, Istanbul",
                "(+02:00) Beirut", 
                "(+02:00) Cairo",
                "(+02:00) Damascus", 
                "(+02:00) Harare, Pretoria",
                "(+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius", 
                "(+02:00) Jerusalem",
                "(+02:00) Minsk",
                "(+03:00) Baghdad",          // 52
                "(+03:00) Kuwait, Riyadh",  
                "(+03:00) Moscow, St. Petersburg, Volgograd",
                "(+03:00) Nairobi",
                "(+03:30) Theran",          // 56
                "(+04:00) Abu Dhabi, Muscat",           // 57
                "(+04:00) Baku",
                "(+04:00) Port Louis", 
                "(+04:00) Tbilisi",
                "(+04:00) Yerevan",
                "(+04:30) Kabul",          // 62
                "(+05:00) Ekaterinburg",            // 63
                "(+05:00) Islamabad, Karachi",
                "(+05:00) Tashkent", 
                "(+05:30) Chennai, Kolkata, Mumbai, New Delhi",          // 66
                "(+05:30) Sri Jayawardenepura", 
                "(+05:45) Kathmandu",          // 68
                "(+06:00) Astana",           // 69
                "(+06:00) Dhaka",
                "(+06:00) Novosibirsk",
                "(+06:30) Yangon (Rangoon)",           // 72
                "(+07:00) Bangkok, Hanoi, Jakarta",          // 73
                "(+07:00) Krasnoyarsk",
                "(+08:00) Beijing, Chongqing, Hong Kong, Urumqi",          // 75
                "(+08:00) Irkutsk",  
                "(+08:00) Kuala Lumpor, Singapore",
                "(+08:00) Perth", 
                "(+08:00) Taipei",
                "(+08:00) Ulaanbaatar", 
                "(+09:00) Osaka, Sapporo, Tokyo",          // 81
                "(+09:00) Seoul", 
                "(+09:00) Yakutsk",
                "(+09:30) Adelaide",          // 84
                "(+09:30) Darwin",
                "(+10:00) Brisbane",            // 86
                "(+10:00) Canberra, Melbourne, Sydney",
                "(+10:00) Guam, Port Moresby", 
                "(+10:00) Hobart",
                "(+10:00) Vladivostok", 
                "(+11:00) Magadan",          // 91
                "(+11:00) Solomon Is., New Caledonia", 
                "(+12:00) Auckland, Wellington",          // 93
                "(+12:00) Coordinated Universal Time +12",
                "(+12:00) Fiji",
                "(+12:30) Nuku'alofa"          // 96
            };

            frmSub.AddChild(new Label("Time Zone", 4, 115));
            Combobox cboTZ = new Combobox(4, 135, frmSub.Width - 8, 20, timeZones);
            cboTZ.SelectedIndex = SettingsManager.BootSettings.TimeZone;
            frmSub.AddChild(cboTZ);

            chkRTC.tapEvent += new OnTap((object sender, point e) => RTCChanged(chkRTC, cboMonth, numDay, numYear, numHour, numMin, numSec, cboAP));

            CommandButton btnCancel = new CommandButton("Cancel", frmSub.Width - 79, frmSub.Height - 29);
            btnCancel.tapEvent += new OnTap((object sender, point e) => API.ActiveForm = frmMain);
            frmSub.AddChild(btnCancel);

            CommandButton btnOK = new CommandButton("Save", frmSub.Width - 158, frmSub.Height - 29);
            btnOK.tapEvent += new OnTap((object sender, point e) => SaveDateTime(chkRTC, cboMonth, numDay, numYear, numHour, numMin, numSec, cboAP, cboTZ));
            frmSub.AddChild(btnOK);

            API.ActiveForm = frmSub;
        }

        private static void ShowNetwork()
        {
            frmSub.ClearChildren();

            frmSub.AddChild(new Label("IP Address:", 24, 30));
            Textbox txtIP = new Textbox(API.MyNetwork.EthernetIPAddress, 99, 28, 100, 20);
            txtIP.Enabled = false;
            frmSub.AddChild(txtIP);

            frmSub.AddChild(new Label("Gateway:", 24, 54));
            Textbox txtGateway = new Textbox(API.MyNetwork.EthernetGatewayAddress, 99, 52, 100, 20);
            txtGateway.Enabled = false;
            frmSub.AddChild(txtGateway);

            frmSub.AddChild(new Label("Subnet Mask:", 24, 78));
            Textbox txtSubnet = new Textbox(API.MyNetwork.EthernetSubnetMask, 99, 76, 100, 20);
            txtSubnet.Enabled = false;
            frmSub.AddChild(txtSubnet);

            frmSub.AddChild(new Label("Connection:", 4, 6));
            Combobox cboNet = new Combobox(70, 4, 70, 20, new string[] { "None", "DHCP", "Static IP" });
            cboNet.SelectedIndexChanged += new OnSelectedIndexChange((object sender, int value) => ConnectionTypeChanged(cboNet, txtIP, txtGateway, txtSubnet));
            cboNet.SelectedIndex = (int)SettingsManager.BootSettings.ConnectionType;
            frmSub.AddChild(cboNet);

            Checkbox chkUpdates = new Checkbox(4, 134);
            chkUpdates.Value = SettingsManager.BootSettings.CheckUpdates;
            frmSub.AddChild(chkUpdates);
            frmSub.AddChild(new Label("Check for updates at start-up", 24, 135));

            CommandButton btnCancel = new CommandButton("Cancel", frmSub.Width - 79, frmSub.Height - 29);
            btnCancel.tapEvent += new OnTap((object sender, point e) => API.ActiveForm = frmMain);
            frmSub.AddChild(btnCancel);

            CommandButton btnOK = new CommandButton("Save", frmSub.Width - 158, frmSub.Height - 29);
            btnOK.tapEvent += new OnTap((object sender, point e) => SaveNetwork(cboNet, txtIP, txtGateway, txtSubnet, chkUpdates));
            frmSub.AddChild(btnOK);

            API.ActiveForm = frmSub;
        }

        private static void ShowServices()
        {
            frmSub.ClearChildren();
            frmSub.Suspended = true;

            PyxisService[] PS = API.GetInstalledServices();

            Combobox cboState = new Combobox(4, 4, frmSub.Width - 8, 20, new string[] { "All", "Running", "Automatic", "Manual", "Disabled" });
            frmSub.AddChild(cboState);

            Listbox lstServices = new Listbox(4, 28, cboState.Width, frmSub.Height - 65);
            for (int i = 0; i < PS.Length; i++)
                lstServices.AddItem(PS[i].Info.Name);

            frmSub.AddChild(lstServices);

            CommandButton btnMode = new CommandButton("Start Mode", 4, frmSub.Height - 29);
            btnMode.tapEvent += new OnTap((object sender, point e) => ChangeServiceStartMode(cboState, lstServices));
            btnMode.Enabled = (lstServices.SelectedIndex > -1);
            frmSub.AddChild(btnMode);

            CommandButton btnStartStop = new CommandButton("Start", 83, frmSub.Height - 29);
            btnStartStop.tapEvent += new OnTap((object sender, point e) => StartStopService(cboState, lstServices, btnStartStop));
            btnStartStop.Enabled = (lstServices.SelectedIndex > -1);
            frmSub.AddChild(btnStartStop);

            CommandButton btnCancel = new CommandButton("Cancel", frmSub.Width - 79, frmSub.Height - 29);
            btnCancel.tapEvent += new OnTap((object sender, point e) => API.ActiveForm = frmMain);
            frmSub.AddChild(btnCancel);

            CommandButton btnOK = new CommandButton("Save", frmSub.Width - 158, frmSub.Height - 29);
            btnOK.tapEvent += new OnTap((object sender, point e) => SaveServices());
            frmSub.AddChild(btnOK);

            cboState.SelectedIndexChanged += new OnSelectedIndexChange((object sender, int e) => CboStateSelChanged(cboState, lstServices));
            lstServices.SelectedIndexChanged += new OnSelectedIndexChange((object sender, int e) => UpdateServiceButtons(cboState, lstServices, btnMode, btnStartStop));
            frmMain.Suspended = false;

            UpdateServiceButtons(cboState, lstServices, btnMode, btnStartStop);
            API.ActiveForm = frmSub;
        }

        private static void ShowSounds()
        {
            if (DeviceManager.ActiveDevice == DeviceType.ChipworkX)
                VS1053.Initialize();
            
            frmSub.ClearChildren();
            frmSub.Suspended = true;

            frmSub.AddChild(new Label("Volume:", 4, 6));
            NumericUpDown numVol = new NumericUpDown(50, 4, 48, 0, 100, SettingsManager.BootSettings.Volume);
            frmSub.AddChild(numVol);

            frmSub.AddChild(new Label("Bass", Colors.Black, FontManager.ArialBold, 4, 30, 30, 20, true, true));
            frmSub.AddChild(new Label("Amplitude:", 24, 47));
            Combobox cboBAmp = new Combobox(85, 45, 70, 20, new string[] { "0.0dB", "1.5dB", "3.0dB", "4.5dB", "6.0dB", "7.5dB", "9.0dB", "10.5dB", "12.0dB", "13.5dB", "15.0dB", "16.5dB", "18.0dB", "19.5dB", "21.0dB", "22.5dB" });
            frmSub.AddChild(cboBAmp);
            frmSub.AddChild(new Label("FQ Limit:", 24, 71));
            Combobox cboBFq = new Combobox(85, 69, 70, 20, new string[] { "0Hz", "10Hz", "20Hz", "30Hz", "40Hz", "50Hz", "60Hz", "70Hz", "80Hz", "90Hz", "100Hz", "110Hz", "120Hz", "130Hz", "140Hz", "150Hz" });
            frmSub.AddChild(cboBFq);


            frmSub.AddChild(new Label("Treble", Colors.Black, FontManager.ArialBold, 154, 30, 36, 20, true, true));
            frmSub.AddChild(new Label("Amplitude:", 174, 47));
            Combobox cboTAmp = new Combobox(235, 45, 70, 20, new string[] { "0.0dB", "1.0dB", "2.0dB", "3.0dB", "4.0dB", "5.0dB", "6.0dB", "7.0dB", "8.0dB", "9.0dB", "10.0dB", "11.0dB", "12.0dB", "13.0dB", "14.0dB", "15.0dB" });
            frmSub.AddChild(cboTAmp);
            frmSub.AddChild(new Label("FQ Limit:", 174, 71));
            Combobox cboTFq = new Combobox(235, 69, 70, 20, new string[] { "0KHz", "1KHz", "2KHz", "3KHz", "4KHz", "5KHz", "6KHz", "7KHz", "8KHz", "9KHz", "10KHz", "11KHz", "12KHz", "13KHz", "14KHz", "15KHz" });
            frmSub.AddChild(cboTFq);

            cboBAmp.SelectedIndexChanged += new OnSelectedIndexChange((object sender, int value) => SetBassTreble(numVol, cboBAmp, cboBFq, cboTAmp, cboTFq));
            cboBFq.SelectedIndexChanged += new OnSelectedIndexChange((object sender, int value) => SetBassTreble(numVol, cboBAmp, cboBFq, cboTAmp, cboTFq));
            cboTAmp.SelectedIndexChanged += new OnSelectedIndexChange((object sender, int value) => SetBassTreble(numVol, cboBAmp, cboBFq, cboTAmp, cboTFq));
            cboTFq.SelectedIndexChanged += new OnSelectedIndexChange((object sender, int value) => SetBassTreble(numVol, cboBAmp, cboBFq, cboTAmp, cboTFq));

            CommandButton cmdPlay = new CommandButton("Play", 4, 100);
            cmdPlay.tapEvent += new OnTap((object sender, point e) => PlayMP3(numVol, cboBAmp, cboBFq, cboTAmp, cboTFq));
            frmSub.AddChild(cmdPlay);

            CommandButton btnCancel = new CommandButton("Cancel", frmSub.Width - 79, frmSub.Height - 29);
            btnCancel.tapEvent += new OnTap((object sender, point e) => API.ActiveForm = frmMain);
            frmSub.AddChild(btnCancel);

            CommandButton btnOK = new CommandButton("Save", frmSub.Width - 158, frmSub.Height - 29);
            btnOK.tapEvent += new OnTap((object sender, point e) => SaveSound(numVol, cboBAmp, cboBFq, cboTAmp, cboTFq));
            frmSub.AddChild(btnOK);

            frmSub.Suspended = false;
            API.ActiveForm = frmSub;
        }

        private static void ConnectionTypeChanged(Combobox cboNet, Textbox txtIP, Textbox txtGateway, Textbox txtSubnet)
        {
            if (cboNet.SelectedIndex == 2)
            {
                txtIP.Enabled = true;
                txtGateway.Enabled = true;
                txtSubnet.Enabled = true;
            }
            else
            {
                txtIP.Enabled = false;
                txtIP.Text = API.MyNetwork.EthernetIPAddress;
                txtGateway.Enabled = false;
                txtGateway.Text = API.MyNetwork.EthernetGatewayAddress;
                txtSubnet.Enabled = false;
                txtSubnet.Text = API.MyNetwork.EthernetSubnetMask;
            }
        }

        private static void CboStateSelChanged(Combobox cboState, Listbox lstServices)
        {
            int i;
            PyxisService[] PS = API.GetInstalledServices();
            lstServices.Clear();

            switch (cboState.SelectedIndex)
            {
                case 0:     // All
                    for (i = 0; i < PS.Length; i++)
                        lstServices.AddItem(PS[i].Info.Name);
                    break;
                case 1:     // Running
                    for (i = 0; i < PS.Length; i++)
                        if (PS[i].Info.IsRunning)
                            lstServices.AddItem(PS[i].Info.Name);
                    break;
                case 2:     // Automatic
                    for (i = 0; i < PS.Length; i++)
                        if (PS[i].Info.StartMode == StartMode.Automatic)
                            lstServices.AddItem(PS[i].Info.Name);
                    break;
                case 3:     // Manual
                    for (i = 0; i < PS.Length; i++)
                        if (PS[i].Info.StartMode == StartMode.Manual)
                            lstServices.AddItem(PS[i].Info.Name);
                    break;
                case 4:     // Disabled
                    for (i = 0; i < PS.Length; i++)
                        if (PS[i].Info.StartMode == StartMode.Disabled)
                            lstServices.AddItem(PS[i].Info.Name);
                    break;
            }
        }

        private static void RTCChanged(Checkbox chkRTC, Combobox cboMonth, NumericUpDown numDay, NumericUpDown numYear, NumericUpDown numHour, NumericUpDown numMin, NumericUpDown numSec, Combobox cboAP)
        {
            cboMonth.Enabled = chkRTC.Value;
            numHour.Enabled = chkRTC.Value;
            numMin.Enabled = chkRTC.Value;
            numSec.Enabled = chkRTC.Value;
            cboAP.Enabled = chkRTC.Value;
            numDay.Enabled = chkRTC.Value;
            numYear.Enabled = chkRTC.Value;
        }

        private static void ChangeServiceStartMode(Combobox cboState, Listbox lstServices)
        {
            PyxisService PS = new PyxisService();
            StartMode SM = (StartMode)API.SelectionDialog("Choose Start Mode", new string[] { "Manual", "Automatic", "Disabled" });

            switch (cboState.SelectedIndex)
            {
                case 0:     // All
                    PS = API.GetInstalledServices()[lstServices.SelectedIndex];
                    break;
                case 1:     // Running
                    PS = API.GetRunningServices()[lstServices.SelectedIndex];
                    break;
                case 2:     // Automatic
                    PS = API.GetServiceByStartMode(StartMode.Automatic)[lstServices.SelectedIndex];
                    break;
                case 3:     // Manual
                    PS = API.GetServiceByStartMode(StartMode.Manual)[lstServices.SelectedIndex];
                    break;
                case 4:     // Disabled
                    PS = API.GetServiceByStartMode(StartMode.Disabled)[lstServices.SelectedIndex];
                    break;
            }

            if (SM == PS.Info.StartMode)
                return;

            PS.Info.StartMode = SM;
            API.UpdateService(PS);

            CboStateSelChanged(cboState, lstServices);
        }

        private static void UpdateServiceButtons(Combobox cboState, Listbox lstServices, CommandButton btnMode, CommandButton btnStartStop)
        {
            // Get Start/Stop Info
            if (lstServices.SelectedIndex == -1)
            {
                btnStartStop.Tag = null;
                btnStartStop.Text = "Start";
            }
            else
            {
                PyxisService PS = new PyxisService();
                switch (cboState.SelectedIndex)
                {
                    case 0:     // All
                        PS = API.GetInstalledServices()[lstServices.SelectedIndex];
                        break;
                    case 1:     // Running
                        PS = API.GetRunningServices()[lstServices.SelectedIndex];
                        break;
                    case 2:     // Automatic
                        PS = API.GetServiceByStartMode(StartMode.Automatic)[lstServices.SelectedIndex];
                        break;
                    case 3:     // Manual
                        PS = API.GetServiceByStartMode(StartMode.Manual)[lstServices.SelectedIndex];
                        break;
                    case 4:     // Disabled
                        PS = API.GetServiceByStartMode(StartMode.Disabled)[lstServices.SelectedIndex];
                        break;
                }
                btnStartStop.Tag = PS;
                btnStartStop.Text = (PS.Info.IsRunning) ? "Stop" : "Start";
            }

            btnMode.Enabled = lstServices.SelectedIndex > -1;
            btnStartStop.Enabled = btnMode.Enabled;
        }

        private static void SaveAppearance(Textbox txtWall, Color colBack, Combobox cboScale, Checkbox chkApp, Checkbox chkFinder, Checkbox chkPic, Checkbox chkSettings)
        {
            MM.Message = "Saving Settings; Please Wait...";
            MM.Start(false);

            // Appearance
            if (txtWall.Enabled)
            {
                if (cboScale.SelectedIndex == 0)
                {
                    API.desktop.UpdateSettings("", colBack, 0, chkApp.Value, chkFinder.Value, chkPic.Value, chkSettings.Value);
                }
                else
                {
                    API.desktop.UpdateSettings(txtWall.Text, colBack, cboScale.SelectedIndex - 1, chkApp.Value, chkFinder.Value, chkPic.Value, chkSettings.Value);
                }
            }

            MM.Stop();
            API.ActiveForm = frmMain;
        }

        private static void SaveDateTime(Checkbox chkRTC, Combobox cboMonth, NumericUpDown numDay, NumericUpDown numYear, NumericUpDown numHour, NumericUpDown numMin, NumericUpDown numSec, Combobox cboAP, Combobox cboTZ)
        {
            MM.Message = "Saving Settings; Please Wait...";
            MM.Start(false);

            SettingsManager.Pyxis2BootSettings ES = SettingsManager.BootSettings;

            SettingsManager.SaveBootSettings(ES.ConnectionType, ES.IPAddress, ES.GatewayAddress, ES.SubnetMask, 
                ES.CheckUpdates, chkRTC.Value, ES.Volume, ES.TrebleAmp, ES.TrebleLimit, ES.BassAmp, ES.BassLimit, 
                cboTZ.SelectedIndex);

            // Real-Time Clock
            if (chkRTC.Value)
                API.SetDateTime(new DateTime(numYear.Value, cboMonth.SelectedIndex + 1, numDay.Value, numHour.Value + ((cboAP.SelectedIndex == 1) ? 12 : 0), numMin.Value, numSec.Value));

            // Time Zone
            TimeService.SetTimeZoneOffset(API.GetTimeZoneMinutes(cboTZ.SelectedIndex));

            MM.Stop();
            API.ActiveForm = frmMain;
        }

        private static void SaveNetwork(Combobox cboNet, Textbox txtIP, Textbox txtGateway, Textbox txtSubnet, Checkbox chkUpdates)
        {
            MM.Message = "Saving Settings; Please Wait...";
            MM.Start(false);

            SettingsManager.Pyxis2BootSettings ES = SettingsManager.BootSettings;

            SettingsManager.SaveBootSettings((NetworkConnectionType)cboNet.SelectedIndex, txtIP.Text, txtGateway.Text,
                txtSubnet.Text, chkUpdates.Value, ES.EnableRTC, ES.Volume, ES.TrebleAmp, ES.TrebleLimit, 
                ES.BassAmp, ES.BassLimit, ES.TimeZone);

            if (DeviceManager.ActiveDevice != DeviceType.Emulator)
            {
                if (API.MyNetwork.AutoConnect != (NetworkConnectionType)cboNet.SelectedIndex)
                {
                    API.MyNetwork.AutoConnect = (NetworkConnectionType)cboNet.SelectedIndex;
                    if (cboNet.SelectedIndex == 2)
                        API.MyNetwork.SetStaticIP(txtIP.Text, txtSubnet.Text, txtGateway.Text);
                }
            }

            MM.Stop();
            API.ActiveForm = frmMain;
        }

        private static void SaveSound(NumericUpDown numVol, Combobox cboBAmp, Combobox cboBFq, Combobox cboTAmp, Combobox cboTFq)
        {
            MM.Message = "Saving Settings; Please Wait...";
            MM.Start(false);

            SettingsManager.Pyxis2BootSettings ES = SettingsManager.BootSettings;
            SettingsManager.SaveBootSettings(ES.ConnectionType, ES.IPAddress, ES.GatewayAddress, ES.SubnetMask, ES.CheckUpdates, 
                ES.EnableRTC, (byte)numVol.Value, (byte)cboTAmp.SelectedIndex, (byte)cboTFq.SelectedIndex, (byte)cboBAmp.SelectedIndex, 
                (byte)cboBFq.SelectedIndex, ES.TimeZone);

            MM.Stop();
            API.ActiveForm = frmMain;
        }

        private static void SaveServices()
        {
        }

        private static void StartStopService(Combobox cboState, Listbox lstServices, CommandButton btnStartStop)
        {
            PyxisService PS = (PyxisService)btnStartStop.Tag;
            if (PS.Info.IsRunning)
                API.StopService(PS.Key);
            else
                API.StartService(PS.Key);

            CboStateSelChanged(cboState, lstServices);
        }

        private static void SaveSettings(Textbox txtWall, Color colBack, Combobox cboScale, Combobox cboNet, Textbox txtIP, Textbox txtGateway, Textbox txtSubnet, Checkbox chkRTC, Combobox cboMonth, NumericUpDown numDay, NumericUpDown numYear, NumericUpDown numHour, NumericUpDown numMin, NumericUpDown numSec, Combobox cboAP, NumericUpDown numVol, Combobox cboBAmp, Combobox cboBFq, Combobox cboTAmp, Combobox cboTFq, Checkbox chkUpdates, Checkbox chkApp, Checkbox chkFinder, Checkbox chkPic, Checkbox chkSettings, Listbox lstServices, Combobox cboTZ)
        {
            MM.Message = "Saving Settings; Please Wait...";
            MM.Start(false);

            // Appearance
            if (txtWall.Enabled)
            {
                if (cboScale.SelectedIndex == 0)
                {
                    API.desktop.UpdateSettings("", colBack, 0, chkApp.Value, chkFinder.Value, chkPic.Value, chkSettings.Value);
                }
                else
                {
                    API.desktop.UpdateSettings(txtWall.Text, colBack, cboScale.SelectedIndex - 1, chkApp.Value, chkFinder.Value, chkPic.Value, chkSettings.Value);
                }
            }

            // Network, Date/Time and Sounds
            SettingsManager.SaveBootSettings((NetworkConnectionType)cboNet.SelectedIndex, txtIP.Text, txtGateway.Text, txtSubnet.Text, chkUpdates.Value, chkRTC.Value, (byte)numVol.Value, (byte)cboTAmp.SelectedIndex, (byte)cboTFq.SelectedIndex, (byte)cboBAmp.SelectedIndex, (byte)cboBFq.SelectedIndex, cboTZ.SelectedIndex);

            if (DeviceManager.ActiveDevice != DeviceType.Emulator)
            {
                if (API.MyNetwork.AutoConnect != (NetworkConnectionType)cboNet.SelectedIndex)
                {
                    API.MyNetwork.AutoConnect = (NetworkConnectionType)cboNet.SelectedIndex;
                    if (cboNet.SelectedIndex == 2)
                    {
                        API.MyNetwork.SetStaticIP(txtIP.Text, txtSubnet.Text, txtGateway.Text);
                    }
                }
            }

            // Real-Time Clock
            if (chkRTC.Value)
                API.SetDateTime(new DateTime(numYear.Value, cboMonth.SelectedIndex + 1, numDay.Value, numHour.Value + ((cboAP.SelectedIndex == 1) ? 12 : 0), numMin.Value, numSec.Value));

            // Time Zone
            TimeService.SetTimeZoneOffset(API.GetTimeZoneMinutes(cboTZ.SelectedIndex));

            // Services
            if (API.MyDrives.RootDirectory != "\\")
            {
                string sName = API.MyDrives.RootDirectory + Resources.GetString(Resources.StringResources.ServicePath);
                string sData = string.Empty;
                byte[] b;
                if (File.Exists(sName))
                    File.Delete(sName);
                FileStream iFile = new FileStream(sName, FileMode.Create, FileAccess.Write);
                for (int i = 0; i < _services.Count; i++)
                    sData += _services[i] + "\n";
                b = UTF8Encoding.UTF8.GetBytes(sData);
                iFile.Write(b, 0, b.Length);
                iFile.Close();
                API.MyDrives.FlushFileSystems();
            }

            MM.Stop();
            Quit();
        }

        private static void PlayMP3(NumericUpDown numVol, Combobox cboBAmp, Combobox cboBFq, Combobox cboTAmp, Combobox cboTFq)
        {
            VS1053.SetVolume((byte)numVol.Value);
            VS1053.SetBassAndTreble((byte)cboBAmp.SelectedIndex, (byte)cboBFq.SelectedIndex, (byte)cboTAmp.SelectedIndex, (byte)cboTFq.SelectedIndex);
            MP3Control.SetSource(API.MyDrives.RootDirectory + "pyxis\\system\\click.mp3");
            MP3Control.Play();
        }

        private static void SetBassTreble(NumericUpDown numVol, Combobox cboBAmp, Combobox cboBFq, Combobox cboTAmp, Combobox cboTFq)
        {
            VS1053.SetVolume((byte)numVol.Value);
            VS1053.SetBassAndTreble((byte)cboBAmp.SelectedIndex, (byte)cboBFq.SelectedIndex, (byte)cboTAmp.SelectedIndex, (byte)cboTFq.SelectedIndex);
        }

        #endregion

    }
}
